package question1.right;

import java.util.concurrent.*;
import java.util.stream.IntStream;

/**
 * 有一批任务需要处理，单个任务耗时事件不确定，请最短时间内处理完这批任务。
 */
public class Main {
    public static void main(String[] args) throws InterruptedException {
//        planA();
//        planB();
        planC();
    }


    // https://www.cnblogs.com/yangzhenlong/p/8359875.html ConcurrentLinkedQueue使用和方法介绍
    public static ConcurrentLinkedQueue<Task> generateTaskQueue(int taskCount) {
        ConcurrentLinkedQueue<Task> taskQueue = new ConcurrentLinkedQueue<>();
        IntStream.range(0, taskCount).mapToObj(Task::new).forEach(taskQueue::add);
        return taskQueue;
    }

    public static void planA() throws InterruptedException {
        ConcurrentLinkedQueue<Task> taskQueue = generateTaskQueue(10);
        Thread t1 = new Thread(new Worker(1, taskQueue));
        Thread t2 = new Thread(new Worker(2, taskQueue));
        Thread t3 = new Thread(new Worker(3, taskQueue));

        t1.start();
        t2.start();
        t3.start();

        t1.join();
        t2.join();
        t3.join();

    }

    public static void planB() throws InterruptedException {
        ConcurrentLinkedQueue<Task> taskQueue = generateTaskQueue(10);

        ExecutorService pool = Executors.newFixedThreadPool(3);
        pool.submit(new Worker(1, taskQueue));
        pool.submit(new Worker(2, taskQueue));
        pool.submit(new Worker(3, taskQueue));
        pool.submit(new Worker(4, taskQueue));

        pool.shutdown();
    }

    public static void planC() throws InterruptedException {
        ConcurrentLinkedQueue<Task> taskQueue = generateTaskQueue(100);

        // https://www.cnblogs.com/Huobn/p/14426814.html  Java ThreadPoolExecutor详解
        ExecutorService pool = new ThreadPoolExecutor(
                0
                , 3
                , 0L
                , TimeUnit.MILLISECONDS
                , new LinkedBlockingQueue<Runnable>(1)
                , Executors.defaultThreadFactory()
                , new ThreadPoolExecutor.AbortPolicy()
        );
        pool.submit(new Worker(1, taskQueue));
        pool.submit(new Worker(2, taskQueue));
        pool.submit(new Worker(3, taskQueue));
//        pool.submit(new Worker(4, taskQueue));

        pool.shutdown();
    }
}
